function ID = C_createVideo(varargin)
%% Setup a Video streamer

global CG;

%% CHECK FOR LAST SESSION ID
if length(varargin)==1 
  ID = varargin{1}; varargin = {};
else
  P = parsePairs(varargin);
  checkField(P,'ID',C_getModuleID('ModuleType','Video'));
  ID = P.ID;
end

%% PARSE INITIALIZATION ARGUMENTS
% PARAMETERS
Pars = C_getParametersModule('ModuleType','Video','IDType',ID);
for iP = 1:length(Pars) checkField(P,Pars{iP}.Name,Pars{iP}.Value); end
% OPTIONS
checkField(P,'Trigger','manual');
checkField(P,'Name',['Video',num2str(ID)]);
checkField(P,'Start',0);
checkField(P,'Reset',0);

%% CHECK WHETHER CHANNELS ALREADY USED
C_discoverVideo; % attach Video to CG if not done before

%% INITIALIZE VIDEO IF NECESSARY
if P.Reset C_resetVideo; end;

%% GET NEW VIDEO SESSION
CG.Sessions.Video(ID).S = videoinput(lower(P.Device),P.CameraID,P.VideoMode);
CG.Sessions.Video(ID).Device = P.Device;
CG.Sessions.Video(ID).Name = P.Name;
CG.Sessions.Video(ID).SR = P.SR;

%% CONFIGURE TRIGGERING FOR THIS VIDEOINPUT (IMMEDIATE FROM GUI, MANUAL FOR EVENTS LATER)
triggerconfig(CG.Sessions.Video(ID).S,P.Trigger);

cS = CG.Sessions.Video(ID).S;
CG.Sessions.Video(ID).Iteration = 0;
CG.Sessions.Video(ID).Source = getselectedsource(cS);
CG.Sessions.Video(ID).SourceInstant = get(imaq.VideoDevice,'DeviceProperties'); 

XPos = find(P.VideoMode=='x'); UPos = find(P.VideoMode=='_');
StartPos = UPos(find(UPos<XPos(end),1,'last'));
StopPos = UPos(find(UPos>XPos(end),1,'first')); if isempty(StopPos) StopPos = length(P.VideoMode)+1; end;
CG.Sessions.Video(ID).Resolution(2) = str2num(P.VideoMode(StartPos+1:XPos(end)-1));
CG.Sessions.Video(ID).Resolution(1) = str2num(P.VideoMode(XPos(end)+1:StopPos-1));
CG.Sessions.Video(ID).PixelsPerFrame = prod(CG.Sessions.Video(ID).Resolution);
CG.Sessions.Video(ID).BytesPerFrame = prod(CG.Sessions.Video(ID).Resolution)*1;
[M1,M2] = memory; 
CG.Sessions.Video(ID).FramesMemoryPhys = M2.PhysicalMemory.Total/CG.Sessions.Video(ID).BytesPerFrame;

%% SETUP INPUT CALLBACK FUNCTION
ControlSamples = lower(P.SR * P.ControlInterval);
CG.Sessions.Video(ID).ControlSamples = ControlSamples;
set(cS,...
  'FramesAcquiredFcnCount',ControlSamples,...
  'FramesAcquiredFcn',{@C_callbackVideoIn,ID},...
  'FramesPerTrigger',1e9,...
  'StopFcn',{@C_CBF_stopVideo,ID},...
  'TriggerFcn',{@C_CBF_triggerVideo,ID},...
  'StartFcn',{@C_CBF_startVideo,ID});

% INITIALIZE BASIC VARIABLES
CG.Display.Video(ID).State = 0;

%% PREPARE OUTPUTs
C_prepareVideoDisplay(ID);

%% START VIDEO
if P.Start C_prepareVideo(ID); C_startVideo(ID); end

function  C_CBF_stopVideo(obj,event,ID)
global CG;
try set(CG.GUI.Main.Modules.Video(ID).StartButton,'Value',0,'BackgroundColor',[1,1,1]); end

function  C_CBF_startVideo(obj,event,ID)
global CG;
try set(CG.GUI.Main.Modules.Video(ID).StartButton,'Value',0,'BackgroundColor',[0,1,0]); end

function  C_CBF_triggerVideo(obj,event,ID)
global CG;
try set(CG.GUI.Main.Modules.Video(ID).StartButton,'Value',1,'BackgroundColor',[1,0,0]); end


